package com.example.widget_lib.widget;

import com.example.widget_lib.utils.AttrUtils;
import com.example.widget_lib.utils.LogUtil;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

import java.util.ArrayList;
import java.util.List;

/**
 * 横向滚动选择view
 */
public class HorScrollSelectedView extends Component implements Component.DrawTask, Component.TouchEventListener {

    // 普通文字的画笔，字体大小，字体颜色
    private Paint mTextPaint;
    private float mTextSize;
    private int mTextColor;
    // 被选中文字的画笔，字体大小，字体颜色
    private Paint mSelectedPaint;
    private float mSelectedTextSize;
    private int mSelectedTextColor;
    // 数据源字符串数组
    private List<String> mStrings = new ArrayList<>();
    private int mSeeSize = 5; // 可见个数
    private int mWidth, mHeight; // 控件宽高
    private int mAnInt; // 每个单元的长度
    private int n; // 中间点索引（选中点）
    private float mAnOffset;
    // 测量文本宽高矩阵
    private Rect mRect = new Rect();
    private boolean mFirstVisible = true;
    // 选中文字的高度
    private int mCenterTextHeight = 0;
    // 文本宽高
    private int mTextWidth, mTextHeight;
    private float mDownX;

    public HorScrollSelectedView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        mContext = context;
        initAttrs(attrSet);
        initPaint();
        setTouchEventListener(this);
        addDrawTask(this);
    }

    @Override
    public void addDrawTask(DrawTask task) {
        super.addDrawTask(task);
        task.onDraw(this, mCanvasForTaskOverContent);
    }

    private void initAttrs(AttrSet attrSet) {
        mSeeSize = AttrUtils.getIntegerFromAttr(attrSet, "seeSize", 5);
        mSelectedTextSize = AttrUtils.getDimensionFromAttr(attrSet, "selectedTextSize", 24);
        mSelectedTextColor = AttrUtils.getColorFromAttr(attrSet, "selectedTextColor", Color.getIntColor("#000000"));
        mTextSize = AttrUtils.getDimensionFromAttr(attrSet, "textSize", 20);
        mTextColor = AttrUtils.getColorFromAttr(attrSet, "textColor", Color.getIntColor("#0a0a0a"));
    }

    private void initPaint() {
        mTextPaint = new Paint();
        mTextPaint.setTextSize((int) mTextSize);
        mTextPaint.setColor(new Color(mTextColor));
        mTextPaint.setAntiAlias(true);
        mSelectedPaint = new Paint();
        mSelectedPaint.setTextSize((int) mSelectedTextSize);
        mSelectedPaint.setColor(new Color(mSelectedTextColor));
        mSelectedPaint.setAntiAlias(true);
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mDownX = event.getPointerPosition(event.getIndex()).getX(); // 获得点下去的x坐标
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                // 抬起手指，偏移量归零，相当于回弹
                mAnOffset = 0;
                invalidate();
                break;
            case TouchEvent.POINT_MOVE:
                float scrollX = event.getPointerPosition(event.getIndex()).getX();
                if (n != 0 && n != mStrings.size() - 1) {
                    mAnOffset = scrollX - mDownX; // 滑动时的偏移量，用于计算每个数据源文字的坐标值
                } else {
                    mAnOffset = (float) ((scrollX - mDownX) / 1.5); // 当滑到两端的时候添加一点阻力
                }
                if (scrollX > mDownX) {
                    // 向右滑动，当滑动距离大于每个单元的长度时，则改变被选中的文字
                    if (scrollX - mDownX >= mAnInt) {
                        if (n > 0) {
                            mAnOffset = 0;
                            n = n - 1;
                            mDownX = scrollX;
                        }
                    }
                } else {
                    // 向左滑动，当滑动距离大于每个单元的长度时，则改变被选中的文字
                    if (mDownX - scrollX >= mAnInt) {
                        if (n < mStrings.size() - 1) {
                            mAnOffset = 0;
                            n = n + 1;
                            mDownX = scrollX;
                        }
                    }
                }
                invalidate();
                break;
            default:
                break;
        }
        return true; // 自己消耗手势，避免只执行move_down，其他move，up不执行
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (mFirstVisible) {
            mWidth = getWidth();
            mHeight = getHeight();
            mAnInt = mWidth / mSeeSize;
        }
        if (n >= 0 && n <= mStrings.size() - 1) {
            String s = mStrings.get(n); // 得到被选中的文字
            // 得到被选中文字，绘制时所需要的宽高
            mRect = mSelectedPaint.getTextBounds(s);
            // 从矩形区域中读出文本内容的宽高
            int centerTextWidth = mRect.getWidth();
            mCenterTextHeight = mRect.getHeight();
            LogUtil.loge("===20190327", "文本内容宽高，宽 = " + centerTextWidth + "->高 = " + mCenterTextHeight + "-n = " + n + "->mAnInt = " + mAnInt);
            canvas.drawText(mSelectedPaint, mStrings.get(n), mWidth / 2 - centerTextWidth / 2 + mAnOffset,
                    mHeight / 2 + mCenterTextHeight / 2); // 绘制被选中文字，注意点是y坐标

            for (int i = 0; i < mStrings.size(); i++) {
                if (n > 0 && n < mStrings.size() - 1) {
                    mRect = mTextPaint.getTextBounds(mStrings.get(n - 1));
                    int widthL = mRect.getWidth();
                    mRect = mTextPaint.getTextBounds(mStrings.get(n + 1));
                    int widthR = mRect.getWidth();
                    mTextWidth = (widthL + widthR) / 2;
                }
                if (i == 0) { // 得到高，高度是一样的，所以取一遍就行
                    mRect = mTextPaint.getTextBounds(mStrings.get(0));
                    mTextHeight = mRect.getHeight();
                }

                if (i != n) { // 绘制其他文本
                    LogUtil.loge("===20190327", "x = " + ((i - n) * mAnInt + mWidth / 2 - mTextWidth / 2 + mAnOffset));
                    // x,y的算法很关键
                    canvas.drawText(mTextPaint, mStrings.get(i),
                            (i - n) * mAnInt + mWidth / 2 - mTextWidth / 2 + mAnOffset,
                            mHeight / 2 + mTextHeight / 2);
                }
            }
        }
    }

    /**
     * 改变中间可见文字的数目
     *
     * @param seeSize 可见数
     */
    public void setSeeSize(int seeSize) {
        if (seeSize > 0) {
            mSeeSize = seeSize;
            invalidate();
        }
    }

    /**
     * 设置数据源
     *
     * @param strings
     */
    public void setData(List<String> strings) {
        mStrings = strings;
        n = mStrings.size() / 2;
        invalidate();
    }

    /**
     * 获得被选中的文本
     *
     * @return 字符串
     */
    public String getSelectedString() {
        if (mStrings.size() != 0) {
            return mStrings.get(n);
        }
        return null;
    }

    /**
     * 设置默认选中索引值
     *
     * @param index
     */
    public void setDefSelectIndex(int index) {
        if (index < 0 || index > mStrings.size() - 1) {
            return;
        }
        n = index;
        invalidate();
    }

    /**
     * 向左移动一个单元
     */
    public void setAnLeftOffset() {
        if (n < mStrings.size() - 1) {
            n = n + 1;
            invalidate();
        }
    }

    /**
     * 向右移动一个单元
     */
    public void setAnRightOffset() {
        if (n > 0) {
            n = n - 1;
            invalidate();
        }
    }

}
